/**
 * 
 */
package edu.gtcfla.km.platform.service.impl;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.vsg.biz.account.Menu;
import org.vsg.biz.account.Permission;
import org.vsg.biz.account.repositories.MenuRepo;
import org.vsg.biz.account.repositories.PermissionRepo;
import org.vsg.biz.account.repositories.UrlRepo;

import edu.gtcfla.km.platform.service.MenuService;
import edu.gtcfla.km.platform.vo.MenuPermissionVO;
import edu.gtcfla.km.platform.vo.MenuVO;

/**
 * @author Bill vison
 *
 */
public class MenuServiceI implements MenuService {


	
	@Autowired
	private MenuRepo menuRepo;
	
	@Autowired
	private UrlRepo urlRepo;
	
	@Autowired
	private PermissionRepo permRepo;
	
	
	/* (non-Javadoc)
	 * @see org.vsg.crm.platform.service.MenuService#buildMenuForPlatform()
	 */
	public Set<MenuVO> buildMenuForPlatform(String prefixPath)  {
		
		
		Set<MenuVO> rootBasicViews = new LinkedHashSet<MenuVO>();
		Sort.Order order = new Sort.Order(Sort.Direction.ASC, "menuLevel");
		Sort sort = new Sort(order);				
		// --- find resource ---
		Iterable<Menu>  menuResSet = (Iterable<Menu>) menuRepo.findAvailable(sort);
		
		Map<String, MenuVO> menuVOMap = new LinkedHashMap<String,MenuVO>();

		Set<Menu> menuWithParentSet = new LinkedHashSet<Menu>();
		
		Set<String> moduleIds = new LinkedHashSet<String>();
		
		for (Menu menu : menuResSet ) {

			MenuVO menuItem = new MenuVO();
			menuItem.setId( menu.getId() );
			menuItem.setText(menu.getName() );
			menuItem.setLeaf(true);
			menuItem.setSortNum( menu.getSortNum() );
			menuItem.setAction( menu.getKeyAction() );

			if (menu.getParent() != null) {
				
				menuWithParentSet.add( menu );
			} 
			
			moduleIds.add( menu.getModuleId() );
			
			menuVOMap.put( menu.getId()  , menuItem);
		}
		
		
		Set<String> dupicateNodeIds = new LinkedHashSet<String>();
		
		// --- with parent ---
		for (Menu menu : menuWithParentSet) {
			String parentId = menu.getParent().getId();

			MenuVO treeNode = menuVOMap.get( parentId );
			if (treeNode == null) {
				// --- remove submenu ---
				menuVOMap.remove( menu.getId() );
				continue;
			}
			treeNode.setLeaf(false);
			
			Set<MenuVO> children = treeNode.getChildren();
			if ( children == null) {
				children = new LinkedHashSet<MenuVO>();
			}
			
			// --- get child node 
			MenuVO child = menuVOMap.get( menu.getId() );
			
			// ---- dupicate node ---
			dupicateNodeIds.add( child.getId() );
			
			children.add( child );
			// --- set tree node ---
			treeNode.setChildren( children );
		}		

		for (String nodeId : dupicateNodeIds) {
			menuVOMap.remove( nodeId );
		}		
		
		List<MenuVO> menus = sortAllMenu(menuVOMap.values());
		
		rootBasicViews.addAll( menus );
		
		// --- sort by sort num ---
		

		return rootBasicViews;

	}
	
	
	private List<MenuVO> sortAllMenu(Collection<MenuVO> sortOrder) {
		List<MenuVO> newList = new ArrayList<MenuVO>( sortOrder);
		Collections.sort(newList, new MenuSorter() );
		
		return newList;
	}

	public Set<MenuPermissionVO> buildPermissionMenuByRoleIds(Set<String> roleIds) {
		
		Set<MenuPermissionVO> menuPerms = new LinkedHashSet<MenuPermissionVO>();
		
		// --- get close role by user ---
		Set<Permission> perms = permRepo.findInMenu(roleIds);

		Sort.Order order = new Sort.Order(Sort.Direction.ASC, "menuLevel");
		Sort sort = new Sort(order);
				
		// --- find resource ---
		Iterable<Menu>  menuResSet = (Iterable<Menu>) menuRepo.findAll(sort);		
		for (Iterator<Menu> menuIter = menuResSet.iterator() ; menuIter.hasNext(); ) {
			Menu menu = menuIter.next();
			MenuPermissionVO permVO = new MenuPermissionVO();
			permVO.setId( menu.getId() );
			for (Permission perm : perms) {
				
				if ( menu.getId().equals( perm.getAssignedResource().getId() )) {
					
					permVO.setId( menu.getId() );
					permVO.setAcl( perm.getAccessControl() );
					menuPerms.add( permVO );
					break;
				}
				
			}			
		}


		return menuPerms;
	}

	
	
}
